package cn.infinite.security.configuration;

import cn.easier.club.base.pool.HttpClientPoolManager;
import cn.infinite.security.core.WxAuthenticateAble;
import cn.infinite.security.core.WxUserService;
import cn.infinite.security.core.impl.DefaultWxAuthenticateService;
import cn.infinite.security.filter.WxCodeAuthenticationFilter;
import cn.infinite.security.handler.DefaultWxAuthenticationFailureHandler;
import cn.infinite.security.handler.DefaultWxAuthenticationSuccessHandler;
import cn.infinite.security.handler.WxAuthenticationFailureHandler;
import cn.infinite.security.handler.WxAuthenticationSuccessHandler;
import cn.infinite.security.provider.WxCodeAuthenticationProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.annotation.Resource;

@Slf4j
@Order(99)
@SuppressWarnings("ALL")
@Configuration
@EnableConfigurationProperties({WxConfigurerProperties.class, SecurityBasicProperties.class})
@ConditionalOnBean(WxUserService.class)
public class WxAuthenticateAutoConfiguration extends WebSecurityConfigurerAdapter {

    @Resource
    private WxConfigurerProperties wxConfigurerProperties;

    @Resource
    private HttpClientPoolManager httpClientPoolManager;

    @Resource
    private WxAuthenticationSuccessHandler wxAuthenticationSuccessHandler;

    @Resource
    private WxAuthenticationFailureHandler wxAuthenticationFailureHandler;

    @Resource
    private WxUserService wxUserService;

    @Resource
    private WxAuthenticateAble wxAuthenticateAble;


    @Bean
    @ConditionalOnMissingBean(HttpClientPoolManager.class)
    public HttpClientPoolManager securityUseHttpClientPoolManager() {
        HttpClientPoolManager httpClientPoolManager = new HttpClientPoolManager(2000, 1000, 2000);
        return httpClientPoolManager;
    }

    @Bean
    @ConditionalOnMissingBean(WxAuthenticateAble.class)
    public WxAuthenticateAble defaultWxAuthenticateService() {
        WxAuthenticateAble wxAuthenticateAble = new DefaultWxAuthenticateService(this.wxUserService, this
                .httpClientPoolManager, this.wxConfigurerProperties);
        return wxAuthenticateAble;
    }

    @Bean
    @ConditionalOnMissingBean(WxAuthenticationSuccessHandler.class)
    public WxAuthenticationSuccessHandler defaultWxAuthenticationSuccessHandler() {
        WxAuthenticationSuccessHandler successHandler = new DefaultWxAuthenticationSuccessHandler(this
                .wxConfigurerProperties);
        return successHandler;
    }

    @Bean
    @ConditionalOnBean(WxAuthenticationFailureHandler.class)
    public WxAuthenticationFailureHandler defaultWxAuthenticationFailureHandler() {
        WxAuthenticationFailureHandler wxAuthenticationFailureHandler = new DefaultWxAuthenticationFailureHandler();
        return wxAuthenticationFailureHandler;
    }

    @Bean
    @ConditionalOnBean(WxCodeAuthenticationFilter.class)
    public WxCodeAuthenticationFilter wxCodeAuthenticationFilter() {
        WxCodeAuthenticationFilter wxCodeAuthenticationFilter = new WxCodeAuthenticationFilter(this
                .wxConfigurerProperties);
        wxCodeAuthenticationFilter.setAuthenticationSuccessHandler(this.wxAuthenticationSuccessHandler);
        wxCodeAuthenticationFilter.setAuthenticationFailureHandler(this.wxAuthenticationFailureHandler);
        return wxCodeAuthenticationFilter;
    }


    @Bean
    public WxCodeAuthenticationProvider wxCodeAuthenticationProvider() {
        WxCodeAuthenticationProvider wxCodeAuthenticationProvider = new WxCodeAuthenticationProvider(this
                .wxAuthenticateAble);
        return wxCodeAuthenticationProvider;
    }

    @Bean
    public WxAuthenticationConfigurerAdapter wxAuthenticationConfigurer() {
        WxAuthenticationConfigurerAdapter wxAuthenticationConfigurer = new WxAuthenticationConfigurerAdapter(this
                .wxCodeAuthenticationFilter(), this.wxCodeAuthenticationProvider());
        return wxAuthenticationConfigurer;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.apply(this.wxAuthenticationConfigurer());
    }
}
